home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / dsp4src / qrmqrn.asm < prev    next >
Encoding:
Assembly Source File  |  1993-04-27  |  4.7 KB  |  163 lines

  1.     page    132,79,1,1
  2.     opt    rc
  3.     title    'LMS AutoNotcher/Denoiser'
  4.  
  5. ;***************************************************************
  6. ;* QRMQRN.ASM -- LMS Automatic Notch and Noise Filter           *
  7. ;*                                   *
  8. ;* Provides Automatic Notch Filter (QRM reductor) and           *
  9. ;* Noise Filter (QRN reductor) based on the LMS algorithm.     *
  10. ;* When compiled with notch=0 noise filter code is activated.  *
  11. ;* When compiled with notch=1 automatic notch filter code is   *
  12. ;* activated.                               *
  13. ;*                                   *
  14. ;* This implementation is for Alef Null DSP CARD 4 with        *
  15. ;* Leonid monitor.                           *
  16. ;*                                   *
  17. ;* Algoriths are based on the book and article               *
  18. ;*    Candy, J., V.:                           *
  19. ;*    "Signal Processing, The Modern Approach",           *
  20. ;*    McGraw-Hill, 1988                       *
  21. ;*                                   *
  22. ;*    Reyer, S., Hershberger, D.:                   *
  23. ;*    "Using The LMS Algorithm For QRM and QRN Reduction",   *
  24. ;*    QEX, September 1992                       *
  25. ;*                                   *
  26. ;* Copyright (C) 1993 by Alef Null. All rights reserved.       *
  27. ;* Author(s): Jarkko Vuori, OH2LNS                   *
  28. ;* Modification(s):                           *
  29. ;***************************************************************
  30.  
  31.  
  32.     nolist
  33.     include 'leonid'                ; DSP CARD 4 monitor equates
  34.     list
  35.  
  36.  
  37. lmslen    equ    24                    ; LMS filter lenght
  38. buflen    equ     8                    ; lenght of sample buffer
  39.  
  40.     if notch
  41. ; Notcher constants
  42. dlen    equ    63                    ; delay line lenght
  43. beta    equ    0.125                    ; adaptation coefficient
  44. decay    equ    0.99915                 ; coefficient decay value
  45.     else
  46. ; Denoiser constants
  47. dlen    equ    1                    ; delay line lenght
  48. beta    equ    0.1875                    ; adaptation coefficient
  49. decay    equ    0.98047                 ; coefficient decay value
  50.     endif
  51.  
  52.  
  53.     org    p:user_code
  54.  
  55. ; initialize address registers
  56.     move            #<buffer+2,r7        ; interrupt handler pointer
  57.     move            #buflen*4-1,m7
  58.  
  59.     move            #<lmscoef,r6        ; LMS filter coeff pointer
  60.  
  61.     move            #<iircoef,r5        ; IIR filter coeff pointer
  62.     move            #4-1,m5
  63.  
  64.     move            #<buffer,r2         ; sample buffer read pointer
  65.     move            #4-2,n2
  66.     move            #buflen*4-1,m2
  67.  
  68.     move            #<dline,r1            ; delay line sample pointer
  69.     move            #dlen+lmslen-1,m1
  70.  
  71. ; initialize codec
  72. ; fs = 16 kHz, line input, headphones and line output, no gain and attenuation
  73.     ctrlcd    1,r2,buflen,LINEI,0.0,0.0,LINEO|HEADP,0.0,0.0
  74.     opencd    16
  75.  
  76. ; wait for one sample
  77. loop    waitblk r2,buflen,1
  78.     move            x:(r2)+,x0            ; read sample from the left channel
  79.  
  80. ; highpass filter the input signal (with one biquad IIR section)
  81.     move            #0.5*g,x1            ; scale input signal
  82.     mpy    x0,x1,a     #<iirs,r0
  83.  
  84.     ori    #$0b,mr                 ; set left shift scaling mode
  85.     move            x:(r0)+,x0    y:(r5)+,y0  ; s1, a1
  86.     mac    -x0,y0,a    x:(r0),x1    y:(r5)+,y0  ; s2, a2
  87.     macr    -x1,y0,a    x0,x:(r0)-    y:(r5)+,y0  ; new s2, get b1
  88.     mac    x0,y0,a     a,x:(r0)    y:(r5)+,y0  ; new s1, get b2
  89.         macr    x1,y0,a
  90.     andi    #$f4,mr                 ; restore scaling mode
  91.  
  92.     move    a,x0                    ; back scaling
  93.     move            #>@cvi(1.0/g+.5),x1
  94.     mpy    x0,x1,a
  95.     asr    a                    ; adjust binary point
  96.     move            a0,x:(r1)+
  97.     move    a0,x1
  98.  
  99. ; Wiener filter convolution part
  100.     clr    a        x:(r1)+,x0    y:(r6)+,y0
  101.     rep    #lmslen-1
  102.     mac    x0,y0,a     x:(r1)+,x0    y:(r6)+,y0
  103.     macr    x0,y0,a     x:(r1)-,x0    y:(r6)-,y0
  104.  
  105.     if !notch
  106. ; store FIR output as a program output if denoiser code
  107.     move            a,y:(r2)+            ; left channel
  108.     move            a,y:(r2)+n2         ; right channel
  109.     endif
  110.  
  111. ; calculate error (e = D - Y) to x1
  112.     neg    a        #decay,y1
  113.     add    x1,a        #beta,x0
  114.     move    a,x1
  115.  
  116.     if notch
  117. ; store error as a program output if notcher code
  118.     move            x1,y:(r2)+            ; left channel
  119.     move            x1,y:(r2)+n2        ; right channel
  120.     endif
  121.  
  122. ; Wiener filter adaptation part
  123.     mpyr    x0,x1,a     r6,r4            ; x1 = beta * e
  124.     move    a,x1
  125.  
  126.     move            x:(r1)-,x0    y:(r6)-,y0  ; get x(0), c(0)
  127.     mpy    y0,y1,a
  128.     macr    x0,x1,a     x:(r1)-,x0    y:(r6)-,y0  ; c(0) = decay * c(0) + e * x(0)
  129.     do    #lmslen-1,adaloop
  130.     mpy    y0,y1,a         a,y:(r4)-   ; save new c
  131.     macr    x0,x1,a     x:(r1)-,x0    y:(r6)-,y0  ; c(n) = decay * c(n) + e * x(n)
  132. adaloop
  133.     move                a,y:(r4)-   ; save c(N)
  134.     move            x:(r1)+,x0    y:(r6)+,y0
  135.     move            x:(r1)+,x0    y:(r6)+,y0
  136.  
  137. ; and do this forever
  138.     jmp    <loop
  139.  
  140.  
  141.     org    x:user_data
  142.  
  143. iirs    ds    2                    ; highpass IIR states
  144.  
  145. buffer    dsm    buflen*4                ; input sample buffer
  146.  
  147. dline    dsm    dlen+lmslen                ; delay line and LMS states
  148.  
  149.  
  150.     org    y:user_data
  151.  
  152. ; 0.5 dB/40 dB elliptic IIR HPF
  153. ; pass 300 Hz, rej 35 Hz
  154. g    equ    0.007                    ; biquad filter scaler
  155. iircoef dc    -1.880563819/2.0,0.8990682309/2.0   ; biquad filter coeffs, a1, a2
  156.     dc    -1.999905221/2.0,1.0/2.0        ;                b1, b2
  157.  
  158.     dsm    buflen*4                ; output sample buffer
  159.  
  160. lmscoef dsm    lmslen                    ; LMS filter coefficients
  161.  
  162.     end
  163.